﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Matlus.FederatedIdentity;
using System.Collections.Specialized;
using System.Text.RegularExpressions;
using System.Web.Security;
namespace GoogleAutWithAsp.Net.GoogleAuth.oAuth
{
    public partial class GoogleValidation : System.Web.UI.Page
    {
        private string realm = null;
        private string provider = "Google";

        protected void Page_Load(object sender, EventArgs e)
        {
            realm = Request.Url.Scheme + "://" + Request.Url.DnsSafeHost + ":" + Request.Url.Port + Request.ApplicationPath;

            if (!IsPostBack)
            {
                if (!String.IsNullOrEmpty(Request.PathInfo))
                {
                    if (Request.PathInfo.StartsWith("/requestToken"))
                        MakeRequestForToken();
                    else if (Request.PathInfo.StartsWith("/authorizeToken"))
                        HandleAuthorizeTokenResponse();
                }
            }
        }

        /// <summary>
        /// Step 1: Get a Request Token
        /// </summary>
        private void MakeRequestForToken()
        {
            string consumerKey = "anonymous";
            string consumerSecret = "anonymous";
            // Google requires an additional "scope" parameter that identifies one of the google applications
            string requestTokenEndpoint = "https://www.google.com/accounts/OAuthGetRequestToken?scope=https://www.googleapis.com/auth/userinfo#email";
            string requestTokenCallback = GetRouteableUrlFromRelativeUrl("GoogleAuth/oAuth/GoogleValidation.aspx/authorizeToken/google/");
            string authorizeTokenUrl = "https://www.google.com/accounts/OAuthAuthorizeToken";

            // Step 1: Make the call to request a token
            var oAuthConsumer = new OAuthConsumer();
            var requestToken = oAuthConsumer.GetOAuthRequestToken(requestTokenEndpoint, realm, consumerKey, consumerSecret, requestTokenCallback);
            PersistRequestToken(requestToken);

            // Step 2: Make a the call to authorize the request token
            Response.Redirect(authorizeTokenUrl + "?oauth_token=" + requestToken.Token);
        }

        private void HandleAuthorizeTokenResponse()
        {
            string consumerKey = "anonymous";
            string consumerSecret = "anonymous";
            string token = Request.QueryString["oauth_token"];
            string verifier = Request.QueryString["oauth_verifier"];
            string accessTokenEndpoint = "https://www.google.com/accounts/OAuthGetAccessToken";

            // Exchange the Request Token for an Access Token
            var oAuthConsumer = new OAuthConsumer();

            var accessToken = oAuthConsumer.GetOAuthAccessToken(accessTokenEndpoint, realm, consumerKey, consumerSecret, token, verifier, GetRequesttoken().TokenSecret);

            //Response.Redirect("~/default.aspx/authenticated/" + provider + "/");

            // Google Only - This method will get the email of the authenticated user
            try
            {

            var responseText = oAuthConsumer.GetUserInfo("https://www.googleapis.com/userinfo/email", realm, consumerKey, consumerSecret, accessToken.Token, accessToken.TokenSecret);           
            string queryString = responseText;
            NameValueCollection nvc = StringToNameValueCollection(responseText);

            if (nvc["email"] != "")
            {
                string userName = nvc["email"];
                //Response.Write("The user's Gmail address is: " + userName);
                Response.Redirect(Request.Url.Scheme.ToString() + "://" + Request.Url.AbsoluteUri.Split('/')[2].ToString() + "/Default.aspx?UserID=" + userName);
            }
            }
            catch (Exception ex)
            {
                Response.Write(ex.Message);                
            }                     
        }

        NameValueCollection StringToNameValueCollection(string queryString)
        {
            NameValueCollection queryParameters = new NameValueCollection();
            string[] querySegments = queryString.Split('&');
            foreach (string segment in querySegments)
            {
                string[] parts = segment.Split('=');
                if (parts.Length > 0)
                {
                    string key = parts[0].Trim(new char[] { '?', ' ' });
                    string val = parts[1].Trim();

                    queryParameters.Add(key, val);
                }
            }
            return queryParameters;
        }


        void PersistRequestToken(RequestToken requestToken)
        {
            Session["RequestToken"] = requestToken;
        }

        RequestToken GetRequesttoken()
        {
            var requestToken = (RequestToken)Session["RequestToken"];
            Session.Remove("RequestToken");
            return requestToken;
        }

        string GetRouteableUrlFromRelativeUrl(string relativeUrl)
        {
            var url = HttpContext.Current.Request.Url;           
            return url.Scheme + "://" + url.Host + ":" + url.Port + VirtualPathUtility.ToAbsolute("~/" + relativeUrl);
        }
    }
}